#!/bin/bash
# filepath: GN

# 切换到家目录保证单用户高分榜单统一，如果多用户统一需要sudo
cd 

export TERM=xterm-256color

# 依赖检查
if ! command -v dialog &>/dev/null || ! command -v jq &>/dev/null; then
    echo "Please install dialog and jq first."
    exit 1
fi

HIGHSCORES_FILE="highscores.json"

# 语言选择
choose_language() {
    LANG_CHOICE=$(dialog --stdout --title "Language/语言" --menu "Select language/选择语言:" 10 30 2 \
        "1" "English" \
        "2" "中文")
    if [ $? -ne 0 ]; then
        clear
        echo "Bye!"
        exit 0
    fi
}

choose_language

# 多语言文本
function t() {
    case "$LANG_CHOICE" in
        1) # English
            case "$1" in
                title) echo "Guess Number Game TUI v2.2" ;;
                menu_start) echo "Start Game" ;;
                menu_help) echo "Help" ;;
                menu_highscore) echo "High Scores" ;;
                menu_lang) echo "Switch Language" ;;
                menu_exit) echo "Exit" ;;
                input_num) echo "Please enter a number (1-100):" ;;
                help_text) echo "[Rules]
1. The system randomly generates an integer between 1 and 100.
2. Each round you have 7 chances to guess.
3. After each guess, you will get a hint: 'Too big' or 'Too small'.
4. Guess right to win, fail after 7 tries.

[Tips]
1. First guess: try 50.
2. Narrow the range by hints (e.g., 50 is too big, next try 25).
3. Watch remaining attempts.
4. Use binary search.

[System]
1. High scores are saved as JSON, top 10 only.
2. Enter nickname after win.
3. High scores auto-saved after game.
4. High scores auto-loaded at start.

[Developer]
1. Author: @BiaoZyx
2. Email: BiaoZyx@outlook.com
3. AI involved in development, suggestions welcome.

Note: Invalid input will cause error." ;;
                win) echo "Congratulations! You guessed it!" ;;
                lose) echo "Game over! The answer was:" ;;
                round) echo "Round %d | Attempts left: %d\nWin: %d  Lose: %d" ;;
                hint_small) echo "Too small" ;;
                hint_big) echo "Too big" ;;
                hint_right) echo "Correct!" ;;
                remain) echo "(Attempts left: %d)" ;;
                last_input) echo "Last input:" ;;
                input_name) echo "Enter your nickname:" ;;
                no_name) echo "Anonymous" ;;
                highscore_title) echo "High Scores (Top 10)" ;;
                developer) echo "Developer: @BiaoZyx | BiaoZyx@outlook.com" ;;
                invalid) echo "Please enter a number between 1 and 100!" ;;
                input_error) echo "Please enter a valid number!" ;;
                exit_confirm) echo "Are you sure you want to exit?" ;;
                exit_msg) echo "Exiting the program..." ;;
                lang_switch) echo "Switch Language" ;;
            esac
            ;;
        2) # 中文
            case "$1" in
                title) echo "猜数字游戏 TUI v2.2" ;;
                menu_start) echo "开始游戏" ;;
                menu_help) echo "帮助" ;;
                menu_highscore) echo "高分榜" ;;
                menu_lang) echo "切换语言" ;;
                menu_exit) echo "退出" ;;
                input_num) echo "请输入1-100之间的数字：" ;;
                help_text) echo "【规则】
1. 系统随机生成1-100的整数。
2. 每轮有7次猜测机会。
3. 每次输入后会提示“大了”或“小了”。
4. 猜中即胜利，7次未中则失败。

【技巧】
1. 首猜建议50。
2. 根据提示缩小范围。
3. 注意剩余次数。
4. 用二分法快速逼近。

【系统】
1. 高分榜以JSON保存，仅前10名。
2. 猜中后输入昵称。
3. 游戏结束自动保存高分榜。
4. 启动时自动加载高分榜。

【开发者】
1. 作者: @BiaoZyx
2. 邮箱: BiaoZyx@outlook.com
3. 本程序有AI参与开发，欢迎建议。

提示：无效输入会提示错误。" ;;
                win) echo "恭喜你猜对了！" ;;
                lose) echo "游戏失败，正确答案：" ;;
                round) echo "第%d轮 | 剩余次数：%d\n胜利：%d  失败：%d" ;;
                hint_small) echo "小了" ;;
                hint_big) echo "大了" ;;
                hint_right) echo "猜对了！" ;;
                remain) echo "（剩余次数：%d）" ;;
                last_input) echo "上次输入：" ;;
                input_name) echo "请输入你的昵称：" ;;
                no_name) echo "无名玩家" ;;
                highscore_title) echo "高分榜（前10）" ;;
                developer) echo "开发者：@BiaoZyx | BiaoZyx@outlook.com" ;;
                invalid) echo "请输入1-100之间的数字！" ;;
                input_error) echo "请输入有效数字！" ;;
                exit_confirm) echo "确定要退出吗？" ;;
                exit_msg) echo "正在退出程序..." ;;
                lang_switch) echo "切换语言" ;;
            esac
            ;;
    esac
}

# 语言切换
switch_language() {
    choose_language
}

# 退出确认
confirm_exit() {
    dialog --title "$(t title)" --yesno "$(t exit_confirm)" 6 40
    if [ $? -eq 0 ]; then
        clear
        echo "$(t exit_msg)"
        exit 0
    fi
}

# 读取高分榜
load_highscores() {
    if [[ -f "$HIGHSCORES_FILE" ]]; then
        cat "$HIGHSCORES_FILE"
    else
        echo "[]"
    fi
}

# 保存高分榜
save_highscores() {
    echo "$1" > "$HIGHSCORES_FILE"
}

# 显示高分榜
show_highscores() {
    local scores=$(load_highscores)
    local list=""
    local count=$(echo "$scores" | jq 'length')
    for ((i=0; i<10 && i<count; i++)); do
        local name=$(echo "$scores" | jq -r ".[$i].name")
        local score=$(echo "$scores" | jq -r ".[$i].score")
        list+="$((i+1)). $name - $score\n"
    done
    dialog --title "$(t highscore_title)" --msgbox "$list" 15 40
}

# 显示帮助
show_help() {
    dialog --title "$(t help)" --msgbox "$(t help_text)" 20 60
}

# 主游戏逻辑
start_game() {
    local win=0
    local lose=0
    local round=1
    local highscores=$(load_highscores)

    while true; do
        local target=$((RANDOM % 100 + 1))
        local attempts=7
        local last_input=""
        local hint=""
        local used_attempts=0

        while (( attempts > 0 )); do
            # 构建显示信息
            local msg
            printf -v msg "$(t round)" "$round" "$attempts" "$win" "$lose"
            msg+="\n$(t last_input) $last_input\n"
            msg+="$(t developer)\n"
            msg+="\n$(t highscore_title):\n"
            for ((i=0; i<3; i++)); do
                local name=$(echo "$highscores" | jq -r ".[$i].name // empty")
                local score=$(echo "$highscores" | jq -r ".[$i].score // empty")
                [[ -n "$name" ]] && msg+="$((i+1)). $name - $score\n"
            done
            msg+="\n$hint"

            # 输入处理循环
            while true; do
                # 显示输入框
                input=$(dialog --clear --title "$(t title)" \
                    --cancel-label "Back" \
                    --inputbox "$msg" 18 60 3>&1 1>&2 2>&3)
                ret=$?
                
                # 处理取消操作
                if [ $ret -eq 1 ] || [ $ret -eq 255 ]; then
                    # 用户按了ESC或取消按钮
                    return  # 直接返回主菜单
                fi

                # 检查输入是否为空
                if [ -z "$input" ]; then
                    dialog --msgbox "$(t input_error)" 7 30
                    continue
                fi

                # 检查是否为有效数字
                if ! [[ "$input" =~ ^[0-9]+$ ]]; then
                    dialog --msgbox "$(t input_error)" 7 30
                    continue
                fi

                # 检查数字范围
                if (( input < 1 || input > 100 )); then
                    dialog --msgbox "$(t invalid)" 7 30
                    continue
                fi

                # 输入有效，退出输入循环
                break
            done

            # 记录输入
            last_input="$input"
            ((attempts--))
            ((used_attempts++))

            # 判断猜测结果
            if (( input < target )); then
                hint="$(t hint_small) $(printf "$(t remain)" "$attempts")"
            elif (( input > target )); then
                hint="$(t hint_big) $(printf "$(t remain)" "$attempts")"
            else
                hint="$(t hint_right)"
                # 猜对了，记录分数
                name=$(dialog --inputbox "$(t input_name)" 8 40 3>&1 1>&2 2>&3)
                [[ -z "$name" ]] && name="$(t no_name)"
                highscores=$(echo "$highscores" | jq --arg n "$name" --argjson s "$used_attempts" \
                    '. += [{"name":$n,"score":$s}] | sort_by(.score) | .[:10]')
                save_highscores "$highscores"
                dialog --msgbox "$(t win)\n$(t developer)\n$target\n$(t remain) $used_attempts" 10 40
                ((win++))
                return  # 返回主菜单
            fi
        done

        # 7次机会用完
        if (( attempts == 0 && input != target )); then
            dialog --msgbox "$(t lose) $target" 8 40
            ((lose++))
        fi

        ((round++))
    done
}

# 主菜单
main_menu() {
    while true; do
        choice=$(dialog --title "$(t title)" --menu "Select an option:" 15 50 5 \
            1 "$(t menu_start)" \
            2 "$(t menu_help)" \
            3 "$(t menu_highscore)" \
            4 "$(t menu_lang)" \
            5 "$(t menu_exit)" \
            3>&1 1>&2 2>&3)
        if [ $? -ne 0 ]; then
            confirm_exit
            continue
        fi
        case $choice in
            1) start_game ;;
            2) show_help ;;
            3) show_highscores ;;
            4) switch_language ;;
            5) confirm_exit ;;
            *) ;;
        esac
    done
}

clear
main_menu
